//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CSpriteBitmap.cpp>
///	@path	~/src/gui/image/
///	@date	2008/06/28
///	@desc	.

#define _FULLAPI
#include "config/config.h"

#include "gui/image/CSpriteBitmap.h"

namespace xeres {

	IMPL_IOBJECT_CLASS( CSpriteBitmap );

	// CSpriteBitmap
	CSpriteBitmap::CSpriteBitmap( size_t width , size_t height , ColorType type , int frames , const byte * src )
		: CColorBitmap( width , height , type )
		, m_frameCount( frames )
	{
		XS_ASSERT( m_frameCount > 0 );
		m_bits = AllocateImage( m_imageSize * m_frameCount );
		byte * bits = m_bits;
		for( int i = 0 ; i < m_frameCount ; ++i , src += m_imageSize , bits += m_imageSize )
		{
			memcpy( bits , src , m_imageSize );
		}
	}
	// CSpriteBitmap
	CSpriteBitmap::CSpriteBitmap( const std::vector<Gdiplus::Bitmap *>& frames )
		: CColorBitmap( *frames[0] )
		, m_frameCount( (int)frames.size() )
	{
		XS_ASSERT( m_frameCount > 0 );
		m_bits = AllocateImage( m_imageSize * m_frameCount );
		byte * bits = m_bits;
		for( int i = 0 ; i < m_frameCount ; ++i , bits += m_imageSize )
		{
			Gdiplus::Bitmap * bmp = frames[i];
			XS_ASSERT( m_type == GetPixelFormatType( bmp ) );
			XS_ASSERT( m_width == bmp->GetWidth() && m_height == bmp->GetHeight() );
			MakeBitmap( bmp , bits );
		}
	}
	// ~CSpriteBitmap
	CSpriteBitmap::~CSpriteBitmap( void )
	{
		// 'm_bits' will be released later.
	}
	// GetFrame
	int CSpriteBitmap::GetFrame( void )
	{
		return m_frameCount;
	}
	// GetDelay
	float CSpriteBitmap::GetDelay( int frame )
	{
		return -1;
	}
	// GetStorageSize
	size_t CSpriteBitmap::GetStorageSize( void )
	{
		return m_imageSize * m_frameCount;
	}
	// GetPixel
	RGBA CSpriteBitmap::GetPixel( const Pair<int>& point , int frame /*= 0 */ )
	{
		XS_ASSERT( point.x < (int)m_width && point.y < (int)m_height );
		XS_ASSERT( frame < m_frameCount );
		byte * base = m_bits + m_imageSize * frame;
		return GetPixelBase( point , base );
	}
	// GetSampler
	void CSpriteBitmap::GetSampler( const Pair<int>& point , Sampler& sampler , int frame /*= 0 */ )
	{
		XS_ASSERT( point.x < (int)m_width && point.y < (int)m_height );
		XS_ASSERT( frame < m_frameCount );
		byte * base = m_bits + m_imageSize * frame;
		sampler.m_bits = GetPixelOffset( point , base );
		sampler.m_pitch = m_pitch;
		sampler.m_type = m_type;
	}

	IMPL_IOBJECT_CLASS( CGifBitmap );

	// CGifBitmap
	CGifBitmap::CGifBitmap( Gdiplus::Bitmap& gif )
		: CColorBitmap( gif )
	{
		using namespace Gdiplus;

		uint count = gif.GetFrameDimensionsCount();
		GUID * pDimensionIDs = (GUID*)new ( alloca( sizeof(GUID)*count) ) GUID[count];
		gif.GetFrameDimensionsList( pDimensionIDs , count );
		WCHAR strGuid[39];
		StringFromGUID2( pDimensionIDs[0] , strGuid , 39 );
		UINT frameCount = gif.GetFrameCount( &pDimensionIDs[0] );

		int size = gif.GetPropertyItemSize( PropertyTagFrameDelay );
		PropertyItem * pItem = NULL;
		pItem = (PropertyItem*)alloca( size );
		gif.GetPropertyItem( PropertyTagFrameDelay , size , pItem );

		XS_ASSERT( frameCount > 0 );

		m_delay.resize( frameCount );
		for( uint i = 0 ; i < frameCount ; ++i )
		{
			int gap = ((int*)pItem->value)[i];
			m_delay[i] = ((float)gap * 10) / 1000.f;
		}

		GUID guid = FrameDimensionTime;
		m_bits = AllocateImage( m_imageSize * frameCount );
		byte * bits = m_bits;
		for( uint i = 0 ; i < frameCount ; ++i , bits += m_imageSize )
		{
			gif.SelectActiveFrame( &guid , i );
			MakeBitmap( &gif , bits );
		}
	}
	// ~CGifBitmap
	CGifBitmap::~CGifBitmap( void )
	{

	}
	// GetFrame
	int CGifBitmap::GetFrame( void )
	{
		return (int)m_delay.size();
	}
	// GetDelay
	float CGifBitmap::GetDelay( int frame )
	{
		XS_ASSERT( frame < (int)m_delay.size() );
		return m_delay[frame];
	}
	// GetStorageSize
	size_t CGifBitmap::GetStorageSize( void )
	{
		return m_imageSize * GetFrame();
	}
	// GetPixel
	RGBA CGifBitmap::GetPixel( const Pair<int>& point , int frame /*= 0 */ )
	{
		XS_ASSERT( point.x < (int)m_width && point.y < (int)m_height );
		XS_ASSERT( frame < (int)m_delay.size() );
		byte * base = m_bits + m_imageSize * frame;
		return GetPixelBase( point , base );
	}
	// GetSampler
	void CGifBitmap::GetSampler( const Pair<int>& point , Sampler& sampler , int frame /*= 0 */ )
	{
		XS_ASSERT( point.x < (int)m_width && point.y < (int)m_height );
		XS_ASSERT( frame < (int)m_delay.size() );
		byte * base = m_bits + m_imageSize * frame;
		sampler.m_bits = GetPixelOffset( point , base );
		sampler.m_pitch = m_pitch;
		sampler.m_type = m_type;
	}

} // namespace xeres
